//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.example.common.util;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

public class GsonUtils {
    public static final boolean SERIALIZE_NULLS = true;
    public static final boolean NOT_SERIALIZE_NULLS = false;
    private static final Gson GSON = createGson(true);
    private static final Gson GSON_NO_NULLS = createGson(false);

    public static Gson createGson() {
        return createGson(true);
    }

    public static Gson createGson(final boolean serializeNulls) {
        GsonBuilder builder = new GsonBuilder();
        if (serializeNulls) {
            builder.serializeNulls();
        }

        return builder.create();
    }

    private static Gson getGson() {
        return GSON;
    }

    private static Gson getGson(final boolean serializeNulls) {
        return serializeNulls ? GSON : GSON_NO_NULLS;
    }

    private GsonUtils() {
        throw new UnsupportedOperationException("Current class can't be instantiated!!!");
    }

    public static String toJson(Object obj) {
        return GSON.toJson(obj);
    }

    public static String toJson(Object obj, boolean serializeNulls) {
        Gson gson = getGson(serializeNulls);
        return gson.toJson(obj);
    }

    public static <T> T fromJson(final String json, Class<T> clazz) {
        return GSON.fromJson(json, clazz);
    }

    public static <T> T fromJson(final String json, Type type) {
        return GSON.fromJson(json, type);
    }

    public static <T> List<T> fromJsonToList(String json, Class<T> clazz, boolean serializeNulls) {
        Type type = new GsonUtils.ParameterizedTypeImpl(clazz);
        List<T> list = (List)(new GsonBuilder()).setDateFormat("yyyy-MM-dd HH:mm:ss").create().fromJson(json, type);
        return list;
    }

    public static Map<String, Object> fromJson(final String json) {
        return (Map)fromJson(json, Map.class);
    }

    public static <T> T copyProperties(Object obj, Class<T> ClassType) {
        return fromJson(toJson(obj), ClassType);
    }

    public static <T> List<T> copyProperties(List<?> obj, Class<T> ClassType, boolean enableSerializeNull) {
        return fromJsonToList(toJson(obj), ClassType, enableSerializeNull);
    }


    public static <T> List<T> copyProperties(List<?> obj, Class<T> ClassType) {
        return fromJsonToList(toJson(obj), ClassType, true);
    }

    private static class ParameterizedTypeImpl implements ParameterizedType {
        Class clazz;

        public ParameterizedTypeImpl(Class clz) {
            this.clazz = clz;
        }

        @Override
        public Type[] getActualTypeArguments() {
            return new Type[]{this.clazz};
        }

        @Override
        public Type getRawType() {
            return List.class;
        }

        @Override
        public Type getOwnerType() {
            return null;
        }
    }
}
